﻿using System.Collections.Generic;
using System.Linq;

namespace ControllerLayer.AStar
{
    internal class PriorityQueue<TKey, TValue>
    {
        private readonly SortedDictionary<TKey, Queue<TValue>> _list = new SortedDictionary<TKey, Queue<TValue>>();

        /// <summary>
        /// Enqueues the specified priority.
        /// </summary>
        /// <param name="priority">The priority.</param>
        /// <param name="value">The value.</param>
        public void Enqueue(TKey priority, TValue value)
        {
            //Queue representing a First-In-First-Out collection
            Queue<TValue> queue;
            //Try to find a queue from a priority value - if found, it sets the local queue to this
            if (!_list.TryGetValue(priority, out queue))
            {
                //If not found, it creates a new queue to add a new priority-queue keypair
                queue = new Queue<TValue>();
                _list.Add(priority, queue);
            }
            //puts the value to the queue
            queue.Enqueue(value);
        }

        /// <summary>
        /// Dequeues the first instance from the queue.
        /// </summary>
        /// <returns></returns>
        public TValue Dequeue()
        {
            //Finds the first key-value pair from the list
            //Here the value is a queue, from where the first element is dequeued
            KeyValuePair<TKey, Queue<TValue>> pair = _list.First();
            TValue value = pair.Value.Dequeue();
            if (pair.Value.Count == 0) // nothing left of the top priority.
            {
                _list.Remove(pair.Key); //Remove the key representing a priority queue
            }
            return value;
        }

        /// <summary>
        /// Gets a value indicating whether [is empty].
        /// </summary>
        /// <value><c>true</c> if [is empty]; otherwise, /c>.</value>
        public bool IsEmpty
        {
            get { return !_list.Any(); }
        }
    }
}